package com.hx.jeeadminbase.utils;

import cn.hutool.core.codec.Base64Decoder;
import cn.hutool.core.codec.Base64Encoder;
import java.math.BigInteger;

/**
 * @Author: xinmiao.xu
 * @Emial: louis_hsu@yeah.net
 * @CreateDate: 2014年9月2日 上午11:11:52
 * @Description: 编码相关工具
 */
public class CodeUtil {

	// ==========================================Native <-> Ascii===================================================//
	/**
	 * 本地码转为ascii编码
	 * @param t
	 * @return
	 */
	public static String native2Unicode(String t) {
		StringBuffer unicode = new StringBuffer();
		char[] charAry = new char[t.length()];
		for (int i = 0; i < charAry.length; i++) {
			charAry[i] = (char) t.charAt(i);
			unicode.append("\\u" + Integer.toString(charAry[i], 16));
		}
		return unicode.toString();
	}

	/**
	 * ascii转为本地码
	 * @param theString
	 * @return
	 */
	public static String unicode2Native(String theString) {
		char aChar;
		int len = theString.length();
		StringBuffer outBuffer = new StringBuffer(len);
		for (int x = 0; x < len;) {
			aChar = theString.charAt(x++);
			if (aChar == '\\') {
				aChar = theString.charAt(x++);
				if (aChar == 'u') {
					int value = 0;
					for (int i = 0; i < 4; i++) {
						aChar = theString.charAt(x++);
						switch (aChar) {
						case '0':
						case '1':
						case '2':
						case '3':
						case '4':
						case '5':
						case '6':
						case '7':
						case '8':
						case '9':
							value = (value << 4) + aChar - '0';
							break;
						case 'a':
						case 'b':
						case 'c':
						case 'd':
						case 'e':
						case 'f':
							value = (value << 4) + 10 + aChar - 'a';
							break;
						case 'A':
						case 'B':
						case 'C':
						case 'D':
						case 'E':
						case 'F':
							value = (value << 4) + 10 + aChar - 'A';
							break;
						default:
							throw new IllegalArgumentException("Malformed   \\uxxxx   encoding.");
						}
					}
					outBuffer.append((char) value);
				} else {
					if (aChar == 't')
						aChar = '\t';
					else if (aChar == 'r')
						aChar = '\r';
					else if (aChar == 'n')
						aChar = '\n';
					else if (aChar == 'f')
						aChar = '\f';
					outBuffer.append(aChar);
				}
			} else
				outBuffer.append(aChar);
		}
		return outBuffer.toString();
	}

	/**
	 * unicode转中文
	 * @param theString
	 * @return
	 */
	public static String decodeUnicode(String theString) {
		char aChar;
		int len = theString.length();
		StringBuffer outBuffer = new StringBuffer(len);
		for (int x = 0; x < len;) {
			aChar = theString.charAt(x++);
			if (aChar == '\\') {
				aChar = theString.charAt(x++);
				if (aChar == 'u') {
					int value = 0;
					for (int i = 0; i < 4; i++) {
						aChar = theString.charAt(x++);
						switch (aChar) {
						case '0':
						case '1':
						case '2':
						case '3':
						case '4':
						case '5':
						case '6':
						case '7':
						case '8':
						case '9':
							value = (value << 4) + aChar - '0';
							break;
						case 'a':
						case 'b':
						case 'c':
						case 'd':
						case 'e':
						case 'f':
							value = (value << 4) + 10 + aChar - 'a';
							break;
						case 'A':
						case 'B':
						case 'C':
						case 'D':
						case 'E':
						case 'F':
							value = (value << 4) + 10 + aChar - 'A';
							break;
						default:
							throw new IllegalArgumentException("Malformed   \\uxxxx   encoding.");
						}
					}
					outBuffer.append((char) value);
				} else {
					if (aChar == 't')
						aChar = '\t';
					else if (aChar == 'r')
						aChar = '\r';
					else if (aChar == 'n')
						aChar = '\n';
					else if (aChar == 'f')
						aChar = '\f';
					outBuffer.append(aChar);
				}
			} else
				outBuffer.append(aChar);
		}
		return outBuffer.toString();
	}

	// ==========================================汉字拼音=============================================================//
	class GD2Alphabet {
		// 字母Z使用了两个标签，这里有２７个值
		// i, u, v都不做声母, 跟随前面的字母
		private char[] chartable = { '啊', '芭', '擦', '搭', '蛾', '发', '噶', '哈', '哈', '击', '喀', '垃', '妈', '拿', '哦', '啪', '期', '然', '撒', '塌', '塌', '塌', '挖', '昔', '压', '匝', '座' };
		private char[] alphatable = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
		private int[] table = new int[27];

		// 初始化
		{
			for (int i = 0; i < 27; ++i) {
				table[i] = gbValue(chartable[i]);
			}
		}

		public GD2Alphabet() {

		}

		// 主函数,输入字符,得到他的声母,
		// 英文字母返回对应的大写字母
		// 其他非简体汉字返回 '0'
		public char Char2Alpha(char ch) {
			if (ch >= 'a' && ch <= 'z') {
				return (char) (ch - 'a' + 'A');
			}
			if (ch >= 'A' && ch <= 'Z') {
				return ch;
			}
			int gb = gbValue(ch);
			if (gb < table[0]) {
				return '0';
			}
			int i;
			for (i = 0; i < 26; ++i) {
				if (match(i, gb)) {
					break;
				}
			}
			if (i >= 26) {
				return '0';
			} else {
				return alphatable[i];
			}
		}

		// 根据一个包含汉字的字符串返回一个汉字拼音首字母的字符串
		public String String2Alpha(String SourceStr) {
			String Result = "";
			int StrLength = SourceStr.length();
			int i;
			try {
				for (i = 0; i < StrLength; i++) {
					Result += Char2Alpha(SourceStr.charAt(i));
				}
			} catch (Exception e) {
				Result = "";
			}
			return Result;
		}

		private boolean match(int i, int gb) {
			if (gb < table[i]) {
				return false;
			}
			int j = i + 1;
			// 字母Z使用了两个标签
			while (j < 26 && (table[j] == table[i])) {
				++j;
			}
			if (j == 26) {
				return gb <= table[j];
			} else {
				return gb < table[j];
			}
		}

		// 取出汉字的编码
		private int gbValue(char ch) {
			String str = new String();
			str += ch;
			try {
				byte[] bytes = str.getBytes("GB2312");
				if (bytes.length < 2) {
					return 0;
				}
				return (bytes[0] << 8 & 0xff00) + (bytes[1] & 0xff);
			} catch (Exception e) {
				return 0;
			}
		}
	}

	/**
	 * 获取汉字拼音首字母
	 * @param ChineseStr
	 * @return
	 */
	public static String getChinesePinYin(String ChineseStr) {
		return new CodeUtil().new GD2Alphabet().String2Alpha(ChineseStr);
	}

	/**
	 * 将byte[]转为各种进制的字符串
	 * @param bytes byte[]
	 * @param radix
	 *        可以转换进制的范围，从Character.MIN_RADIX到Character.MAX_RADIX，超出范围后变为10进制
	 * @return 转换后的字符串
	 */
	public static String binary(byte[] bytes, int radix) {
		return new BigInteger(1, bytes).toString(radix);// 这里的1代表正数
	}

	/**
	 * base 64 encode
	 * @param bytes 待编码的byte[]
	 * @return 编码后的base 64 code
	 */
	@SuppressWarnings("restriction")
	public static String base64Encode(byte[] bytes) {
		//return new sun.misc.BASE64Encoder().encode(bytes);
		return new Base64Encoder().encode(bytes);
	}

	/**
	 * base 64 decode
	 * @param base64Code 待解码的base 64 code
	 * @return 解码后的byte[]
	 * @throws Exception
	 */
	@SuppressWarnings("restriction")
	public static byte[] base64Decode(String base64Code) throws Exception {
		return StringUtil.isEmptyStr(base64Code) ? null : new Base64Decoder().decode(base64Code);//decodeBuffer(base64Code);
	}

	/**
	 * 解码base64编码的字符串,并指定字符集
	 * @param base64Code
	 * @param charset
	 * @return
	 * @throws Exception
	 */
	public static String base64DecodeStr(String base64Code, String charset) throws Exception {
		byte[] rs = base64Decode(base64Code);
		if (rs != null && rs.length > 0) {
			return new String(rs, charset);
		}
		return null;
	}

	/**
	 * 解码base64编码的字符串,utf-8编码
	 * @param base64Code
	 * @return
	 * @throws Exception
	 */
	public static String base64DecodeStr(String base64Code) throws Exception {
		byte[] rs = base64Decode(base64Code);
		if (rs != null && rs.length > 0) {
			return new String(rs, "utf-8");
		}
		return null;
	}

	public static void main(String[] args) {
		String url = "http://lovejuanyao.tunnel.2bdata.com/main";//"http://weixin.grace520.com/wx/sell";  //http://lovejuanyao.tunnel.2bdata.com/main
		String str64 = base64Encode(url.getBytes());
		System.out.println(str64);
		//System.out.println(native2Unicode("颐而康"));
	}
}
